package org.metasketch.diagram.javafx.graphics;

import org.metasketch.editor.timeline.SnapshotManager;

import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;

public class SelectBox extends Group implements EventHandler<MouseEvent> {

	BaseGraphic baseGraphic;

	Rectangle boundBox = new Rectangle(-5, -5, 5, 5);
	Line left = new Line();
	Line right = new Line();
	Line top = new Line();
	Line bottom = new Line();

	int cornerWidth = 12;

	Rectangle topLeftCorner = new Rectangle(0, 0, cornerWidth, cornerWidth);
	Rectangle topRightCorner = new Rectangle(0, 0, cornerWidth, cornerWidth);
	Rectangle bottomLeftCorner = new Rectangle(0, 0, cornerWidth, cornerWidth);
	Rectangle bottomRightCorner = new Rectangle(0, 0, cornerWidth, cornerWidth);

	protected boolean selected = false;

	protected Resizableness resizableness = Resizableness.BOTH;

	private boolean moving;

	public SelectBox(BaseGraphic baseGraphic) {
		this.baseGraphic = baseGraphic;

		boundBox.setStyle("-fx-fill: transparent; -fx-stroke: gray;  -fx-stroke-type: outside;  -fx-stroke-width: 5;   -fx-stroke-dash-array: 12 2 4 2;    -fx-stroke-dash-offset: 6;     -fx-stroke-line-cap: butt; -fx-opacity: 0.5;");

		// lines
		left.setStyle("-fx-fill: transparent; -fx-stroke: gray;  -fx-stroke-type: centered;  -fx-stroke-width: 12;   -fx-stroke-dash-array: 1 1;    -fx-stroke-dash-offset: 6;     -fx-stroke-line-cap: butt; ");
		right.setStyle("-fx-fill: transparent; -fx-stroke: gray;  -fx-stroke-type: centered;  -fx-stroke-width: 12;   -fx-stroke-dash-array: 1 1;    -fx-stroke-dash-offset: 6;     -fx-stroke-line-cap: butt; ");
		top.setStyle("-fx-fill: transparent; -fx-stroke: gray;  -fx-stroke-type: centered;  -fx-stroke-width: 12;   -fx-stroke-dash-array: 1 1;    -fx-stroke-dash-offset: 6;     -fx-stroke-line-cap: butt; ");
		bottom.setStyle("-fx-fill: transparent; -fx-stroke: gray;  -fx-stroke-type: centered;  -fx-stroke-width: 12;   -fx-stroke-dash-array: 1 1;    -fx-stroke-dash-offset: 6;     -fx-stroke-line-cap: butt; ");

		left.setOnMouseDragged(this);
		right.setOnMouseDragged(this);
		top.setOnMouseDragged(this);
		bottom.setOnMouseDragged(this);

		// Squares
		topLeftCorner
				.setStyle("-fx-fill: ghostwhite ; -fx-stroke: gray;  -fx-stroke-type: centered;  -fx-stroke-width: 1;  ");
		topRightCorner
				.setStyle("-fx-fill: ghostwhite ; -fx-stroke: gray;  -fx-stroke-type: centered;  -fx-stroke-width: 1;   ");
		bottomLeftCorner
				.setStyle("-fx-fill: ghostwhite ; -fx-stroke: gray;  -fx-stroke-type: centered;  -fx-stroke-width: 1;  ");
		bottomRightCorner
				.setStyle("-fx-fill: ghostwhite ; -fx-stroke: gray;  -fx-stroke-type: centered;  -fx-stroke-width: 1;  ");

		topLeftCorner.setOnMouseDragged(this);
		topRightCorner.setOnMouseDragged(this);
		bottomLeftCorner.setOnMouseDragged(this);
		bottomRightCorner.setOnMouseDragged(this);

		getChildren().addAll(left, right, top, bottom, topLeftCorner,
				topRightCorner, bottomLeftCorner, bottomRightCorner);
	}

	public void setSelected(boolean selected) {
		if (this.selected == selected)
			return;

		// TODO showBoundBox, add mouse for resize if resizable
		if (selected) {

			resizeSelectBox();

			// boundBox.setWidth(baseGraphic.getWidth() + 12);
			// boundBox.setHeight(baseGraphic.getHeight() + 12);

			// baseGraphic.getChildren().add(boundBox);

			// boundBox.setWidth(baseGraphic.getWidth() + 12);
			// boundBox.setHeight(baseGraphic.getHeight() + 12);

			baseGraphic.getChildren().add(this);

		} else {

			baseGraphic.getChildren().remove(this);
		}

		this.selected = selected;

	}

	@Override
	public void handle(MouseEvent event) {

		System.out.println("Select box: " + event);

		if (resizableness == Resizableness.NONE)
			return;

		if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
			if (!moving)
				moving = true;
		}
		// this never gets picked up by this node, only by the default select
		// tool
		// else if (event.getEventType() == MouseEvent.MOUSE_CLICKED && moving)
		// {
		//
		// moving = false;
		// SnapshotManager.takeSnapshot();
		// }

		Object source = event.getSource();

		if (source == left
				&& (resizableness == Resizableness.BOTH || resizableness == Resizableness.HORIZONTAL)) {
			resizeLeft(event);
		} else if (source == top
				&& (resizableness == Resizableness.BOTH || resizableness == Resizableness.VERTICAL)) {
			resizeUp(event);
		} else if (source == right
				&& (resizableness == Resizableness.BOTH || resizableness == Resizableness.HORIZONTAL)) {
			resizeRight(event);
		} else if (source == bottom
				&& (resizableness == Resizableness.BOTH || resizableness == Resizableness.VERTICAL)) {
			resizeBottom(event);
		} else if (source == bottomRightCorner) {

			if (resizableness == Resizableness.BOTH) {

				baseGraphic.resize(baseGraphic.getWidth() + (int) event.getX(),
						baseGraphic.getHeight() + (int) event.getY());
			} else if (resizableness == Resizableness.VERTICAL) {
				baseGraphic.resize(baseGraphic.getWidth(),
						baseGraphic.getHeight() + (int) event.getY());
			} else if (resizableness == Resizableness.HORIZONTAL) {
				baseGraphic.resize(baseGraphic.getWidth() + (int) event.getX(),
						baseGraphic.getHeight());
			}

		} else if (source == topLeftCorner) {
			if (resizableness == Resizableness.BOTH) {

				baseGraphic.setPosition(
						baseGraphic.getX() + (int) event.getX(),
						baseGraphic.getY() + (int) event.getY());
				baseGraphic.resize(baseGraphic.getWidth() - (int) event.getX(),
						baseGraphic.getHeight() - (int) event.getY());

			} else if (resizableness == Resizableness.VERTICAL) {
				resizeUp(event);
			} else if (resizableness == Resizableness.HORIZONTAL) {
				resizeLeft(event);
			}

		} else if (source == topRightCorner) {

			if (resizableness == Resizableness.BOTH) {
				baseGraphic.setY(baseGraphic.getY() + (int) event.getY());

				baseGraphic.resize(baseGraphic.getWidth() + (int) event.getX(),
						baseGraphic.getHeight() - (int) event.getY());

			} else if (resizableness == Resizableness.VERTICAL) {
				resizeUp(event);
			} else if (resizableness == Resizableness.HORIZONTAL) {
				baseGraphic.resize(baseGraphic.getWidth() + (int) event.getX(),
						baseGraphic.getHeight());
			}

		} else if (source == bottomLeftCorner) {

			if (resizableness == Resizableness.BOTH) {
				baseGraphic.setX(baseGraphic.getX() + (int) event.getX());

				baseGraphic.resize(baseGraphic.getWidth() - (int) event.getX(),
						baseGraphic.getHeight() + (int) event.getY());
			} else if (resizableness == Resizableness.VERTICAL) {
				baseGraphic.resize(baseGraphic.getWidth(),
						baseGraphic.getHeight() + (int) event.getY());
			} else if (resizableness == Resizableness.HORIZONTAL) {
				resizeLeft(event);
			}

		}

		event.consume();

		resizeSelectBox();

	}

	protected void resizeBottom(MouseEvent event) {
		baseGraphic.setHeight((int) event.getY());
	}

	protected void resizeRight(MouseEvent event) {
		baseGraphic.setWidth((int) event.getX());
	}

	protected void resizeUp(MouseEvent event) {
		baseGraphic.setY(baseGraphic.getY() + (int) event.getY());
		baseGraphic.setHeight(baseGraphic.getHeight() - (int) event.getY());
	}

	protected void resizeLeft(MouseEvent event) {
		baseGraphic.setX(baseGraphic.getX() + (int) event.getX());
		baseGraphic.setWidth(baseGraphic.getWidth() - (int) event.getX());
	}

	protected void resizeSelectBox() {
		int leftSide = -5;
		int topSide = -5;

		int rightSide = baseGraphic.getWidth() + 7;
		int bottomSide = baseGraphic.getHeight() + 7;

		left.setStartX(leftSide);
		left.setStartY(topSide);

		left.setEndX(leftSide);
		left.setEndY(bottomSide);

		right.setStartX(rightSide);
		right.setStartY(topSide);

		right.setEndX(rightSide);
		right.setEndY(bottomSide);

		top.setStartX(leftSide);
		top.setStartY(topSide);

		top.setEndX(rightSide);
		top.setEndY(topSide);

		bottom.setStartX(leftSide);
		bottom.setStartY(bottomSide);

		bottom.setEndX(rightSide);
		bottom.setEndY(bottomSide);

		// TODO setup the corners
		topLeftCorner.setTranslateX(leftSide - 6);
		topLeftCorner.setTranslateY(topSide - 6);

		topRightCorner.setTranslateX(rightSide - 6);
		topRightCorner.setTranslateY(topSide - 6);

		bottomLeftCorner.setTranslateX(leftSide - 6);
		bottomLeftCorner.setTranslateY(bottomSide - 6);

		bottomRightCorner.setTranslateX(rightSide - 6);
		bottomRightCorner.setTranslateY(bottomSide - 6);

	}

	// public boolean isResizable() {
	// return resizable;
	// }

	public void setResizable(Resizableness resizableness) {
		this.resizableness = resizableness;
	}

	public boolean isSelected() {
		return selected;
	}

	public boolean isMoving() {
		return moving;
	}

	public void setMoving(boolean b) {
		moving = b;

	}

}
